<template>
  <div>
    <NuxtLayout name="default">
      <modelS></modelS>
      <TheGuidedPopup ref="guidedPopupRef"/>
    </NuxtLayout>
  </div>
</template>
<script setup lang="ts">
import modelS from "~/components/modelv1/index.vue";
import {getchatLog, samplesLists, cleanChat, chatSendText} from '@/api/chat'
import {useUserStore} from '~~/stores/user'
import feedback from '~~/utils/feedback'
import {ElButton, ElMessageBox, ElScrollbar} from 'element-plus'
import {useAppStore} from '~/stores/app'
import {isNewDay} from '~/utils/validate'

const formData = ref<any>({})
import {CHAT_LIMIT_KEY, CHAT_MODEL_KEY, PLUGIN_MODEL_KEY} from '~/enums/cacheEnums'
import {watch} from 'vue'

const formDesignerRef = shallowRef()
import TheSessionv1 from '@/components/the-session/indexv1.vue'
import ModelPicker from "~/components/chatting/model-picker.vue";
import {getCreationDetail} from "~/api/create";
import {cloneDeep} from "lodash-es";

const userStore = useUserStore()
const appStore = useAppStore()
const router = useRouter()
const route = useRoute()
const currentId = ref(Number(route.query.id))
if(currentId.value > 0) {
   window.localStorage.setItem('other_id',currentId.value)
}
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>(null)
const currentCreationHistory = ref<any[]>([])
//对话记录列表
const dialogTableVisible = ref(false)

//对话记录列表
const isFrom = ref(true)

const sendDisabled = ref(false)

//对话框ref
const chattingRef = ref(null)
const guidedPopupRef = shallowRef()
// 聊天次数(消耗
const chatModelConfig = ref({
  balance: 1,
  member_free: false
})
const chatModel = ref<string>('')
const chatParams = reactive({
  model: '',
  network: false
})

const plugins = reactive({
  type: '',
  id: '',
  file: {} as any
})

const updateHide = (value) => {
  //sessionActive.value = value
  chatLogParams.category_id = value
  getChatList()
  dialogTableVisible.value = false
}

const insertExample = () => {
  modelData.value?.form.forEach((item: any) => {
    if (item.props.placeholder && !item.props.defaultValue) {

      formData.value[item.id] = item.props.placeholder
    }
  })
}

const strmx = ref<any>({})


const setFormDataDefault = () => {
  modelData.value?.form.forEach((item: any) => {
    if (item.props.defaultValue) {
      formData.value[item.id] = cloneDeep(item.props.defaultValue)
    } else {
      formData.value[item.id] = undefined
    }
  })
}


const back = () => {
  router.push('/create')
}

const getCountMsg = computed(() => {
  if (!chatModelConfig.value.key) return ''
  if (!chatModelConfig.value.member_free) {
    if (chatModelConfig.value.balance) {
      return `消耗 ${chatModelConfig.value.balance} 条对话`
    } else {
      return '免费'
    }
  } else {
    return '会员免费'
  }
})

const resetPluginData = () => {
  plugins.file = {url: ''}
}


const handleCreate = async () => {

  try {
    await formDesignerRef.value?.validate()
  } catch (error) {
    feedback.msgError('必填项不能为空')
    return
  }
  if (userStore.userInfo.is_chat_limit && isNewDay(true, CHAT_LIMIT_KEY)) {
    try {
      await ElMessageBox.confirm(
          '已超过会员对话上限次数，继续对话将会消耗账户的对话余额',
          '对话上限提示',
          {
            showClose: false,
            confirmButtonText: '继续',
            cancelButtonText: '关闭'
          }
      )
    } catch (e) {
      return
    }
  }

  // 保存聊天模型（用于刷新之后还能记住当前聊天模型
  const model = useCookie(CHAT_MODEL_KEY)
  model.value = chatModel.value
  let str = ''
  for (const key in modelData.value.form) {
    let id = modelData.value.form[key].id
    let value = formData.value[id] ? formData.value[id] : ''
    str += `${modelData.value.form[key].props.title}:${value} `
  }
  isFrom.value = false
  contentPost(formData.value, 0, str)

}


watch(
    () => plugins.id,
    (val) => {
      if (val == 'gpt-4-all') {
        resetPluginData()
      }
    }
)
const {
  sessionActive,
  sessionAdd,
  currentSession,
  sessionEdit,
  getSessionLists
} = await useSessionList()


const addFrom = () => {
  isFrom.value = true
}

const addMsg = (index?: number) => {
  if(currentId.value > 0) {
    useAsyncData(() => getSessionLists(2, currentId.value), {
      default() {
        return []
      },
      immediate: true
    })
    setTimeout(function () {
      dialogTableVisible.value = true
    }, 300)
  }
}

const chatContentList = ref<any[]>([])
const chatLogParams = reactive({
  type: 2,
  category_id: sessionActive.value,
  page_type: 1,
  page_no: 1,
  page_size: 15
})
const hasMoreDialogueRecords = ref<boolean>(false)
const dialogueRecordsLoading = ref<boolean>(false)

/**
 * 1.上拉加载
 * 2.切换分类时重制上拉
 * 3.对话以后加载(最新一条就行)
 * flag = 1的时候表示对话结束了，获取最新一条数据
 **/
let contentListHeight = 0 // 旧记录高度，新记录高度 - 旧记录高度得到最新刷新定位位置
//获取聊天记录
const getChatList = async (flag?: boolean) => {
  dialogueRecordsLoading.value = true
  hasMoreDialogueRecords.value = true
  try {
    const chatElement = document.getElementsByClassName('contentList')[0]
    const data = await getchatLog({
      ...chatLogParams,
      page_no: flag ? 1 : chatLogParams.page_no,
      page_size: flag ? 1 : chatLogParams.page_size
    })

    const {page_no, page_size} = chatLogParams
    if (
        page_no * page_size > data.count ||
        chatContentList.value.length / 2 >= data.count
    ) {
      hasMoreDialogueRecords.value = false
    }

    const transformData = data.lists.map((item: any) => {
      if (item.type == 1) {
        return {...item, from_avatar: userStore.userInfo.avatar}
      } else {
        return {
          ...item,
          from_avatar: appStore.config.chat.chat_logo
        }
      }
    })

    if (flag) {
      chatContentList.value.splice(-2, 2)
      chatContentList.value = [...chatContentList.value, ...transformData]
    } else {
      chatContentList.value = [...transformData, ...chatContentList.value]
    }

    // 刷新记录时将滚动条定位到刷新之前的元素那里
    await nextTick()
    if (currentSession.value == '新的会话') {
      //  chatContentList.value = []
      //return
    }
    const rect = Object.freeze(chatElement?.getBoundingClientRect())
    if (rect && contentListHeight) {
      chattingRef.value?.scrollTo(rect.height - contentListHeight)
    }
    contentListHeight = rect.height
  } catch (e) {
    console.log('聊天记录错误', e)
  } finally {
    dialogueRecordsLoading.value = false
  }
}

const handleTop = () => {
  if (hasMoreDialogueRecords.value && contentListHeight) {
    chatLogParams.page_no += 1
    getChatList()
  }
}

const qingkong = () => {
  chatLogParams.category_id = -1
  sessionActive.value = -1
  chatContentList.value = []
  chatLogParams.page_no = 1
  getChatList()
}

const {pauseAll} = useAudioPlay()
const isReceiving = ref(false)
const newUserInput = ref<string>('')
//发送问题
const contentPost = async (userInput: any, type = 1, str = '') => {
  if (!userStore.isLogin) return userStore.toggleShowLogin(true)
  if (isReceiving.value) return
  isReceiving.value = true
  sendDisabled.value = true
  if (userStore.userInfo.is_chat_limit && isNewDay(true, CHAT_LIMIT_KEY)) {
    try {
      await ElMessageBox.confirm(
          '已超过会员对话上限次数，继续对话将会消耗账户的对话余额',
          '对话上限提示',
          {
            showClose: false,
            confirmButtonText: '继续',
            cancelButtonText: '关闭'
          }
      )
    } catch (e) {
      isReceiving.value = false
      return
    }
  }

  if (type == 0 || sessionActive.value == -1) {
    await sessionAdd(2, currentId.value)
  }
  if (sessionActive.value == -1 || currentSession.value === '新的会话') {
    await sessionEdit(sessionActive.value, str)
  }
  newUserInput.value = userInput
  chatContentList.value.push({
    type: 1,
    content: userInput,
    from_avatar: userStore.userInfo.avatar,
    file_url: plugins.file.url,
    file_name: plugins.file.name,
    file_type: plugins.type == '' ? 0 : plugins.type == 'image' ? 1 : 2
  })
  const result = reactive({
    type: 2,
    loading: true,
    content: [],
    create_time: ' ',
    from_avatar: appStore.config.chat.chat_logo,
    id: ''
  })
  chatContentList.value.push(result)

  console.log(chatContentList)

  // 缓存使用的插件id
  const pluginId = useCookie(PLUGIN_MODEL_KEY)
  pluginId.value = plugins.id

  try {
    await chatSendText(
        {
          question: userInput,
          type: 2,
          other_id: currentId.value,
          category_id: sessionActive.value,
          ...chatParams,
          model: plugins.id ? plugins.id : chatParams.model,
          file: plugins.file.url,
          is_custom_dialogue: type,
          is_immediately: type == 0 ? 1 : 0
        },
        {
          onstart(reader) {
            streamReader = reader
            pauseAll()
          },
          onmessage(value) {
            value
                .trim()
                .split('data:')
                .forEach(async (text) => {
                  if (text !== '') {
                    try {
                      const dataJson = JSON.parse(text)
                      const {
                        id: chatId,
                        code,
                        event,
                        data,
                        index,
                        incremental
                      } = dataJson
                      if (event == 'error' && code === 101) {
                        guidedPopupRef.value?.open()
                      } else if (event == 'error') {
                        feedback.msgError(data)
                        chattingRef.value.setInput(
                            newUserInput.value
                        )
                      }

                      if (data) {
                        if (!result.content[index]) {
                          result.content[index] = ''
                        }
                        result.content[index] = incremental
                            ? result.content[index] + data
                            : data
                      }
                      if (event === 'finish') {
                        result.loading = false

                        if (plugins.id == 'gpt-4-all') {
                          resetPluginData()
                        }
                        return
                      }
                    } catch (error) {
                    }
                  }
                })
          },
          onclose() {
            isReceiving.value = false
            sendDisabled.value = false
            setTimeout(async () => {
              await getChatList(true)
              await nextTick()
              chattingRef.value.scrollToBottom()
            }, 600)
            userStore.getUser()
          }
        }
    )
  } catch (error) {
    console.log(error)
    isReceiving.value = false
    sendDisabled.value = false
    chattingRef.value.setInput(newUserInput.value)
    chatContentList.value.splice(chatContentList.value.length - 2, 2)
  }

  nextTick(() => {
    chattingRef.value.scrollToBottom()
  })
}

let streamReader: ReadableStreamDefaultReader<Uint8Array> | null = null
const chatClose = (index?: number) => {
  streamReader?.cancel()
  if (index) {
    chatContentList.value[index].loading = false
  }
  isReceiving.value = false
}

//清空会话
const cleanChatLog = async () => {
  await sessionAdd(2, currentId.value)
}



onMounted(async () => {
  if (route.query.cid || route.query.user_sn) {
    const cid: any = useCookie('cid')
    const user_sn: any = useCookie('user_sn')
    cid.value = route.query.cid
    user_sn.value = route.query.user_sn
    await nextTick()
    userStore.checkShare()
  }
  chatContentList.value = []
  sessionActive.value = -1
  chatLogParams.category_id = -1
  await getChatList()
  await nextTick()
  chattingRef.value.scrollToBottom()
})
watch(sessionActive, async (v1) => {
  // 切换对话重置分页数据 Start
  chatLogParams.category_id = v1
  chatLogParams.page_no = 1
  chatContentList.value = []
  contentListHeight = 0
  // 切换对话重置分页数据 End
  chatClose()
  ///await getChatList()
  await nextTick()
  chattingRef.value.scrollToBottom()
})

definePageMeta({
  layout: false
})
</script>
<style lang="scss" scoped>
.container-tip {
  border: 1px solid #fb9a3b;
}

.item {
  :hover {
    color: #fb9a3b;
  }
}

.back {
  position: absolute;
  top: 20px;
  background: white;
  padding: 5px;
  border-radius: 5px;
  color: #7c776e;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  z-index: 9999;
}
.chat-item[data-v-fc8ab866] {
  width: 100%;
  display: flex;
  max-width: 1280px;
}
.ai-avatar[data-v-fc8ab866] {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  overflow: hidden;
  margin-right: 13px;
}
.not-chat-content[data-v-fc8ab866] {
  width: 80%;
  background: rgba(250,251,255,.8);
  padding: 20px;
  box-sizing: border-box;
  border-radius: 8px;
}
.fill img[data-v-12bde410] {
  width: 100%;
  height: 100%;
}
.welcome-content[data-v-fc8ab866] {
  width: 100%;
}
.welcome-name[data-v-fc8ab866] {
  width: 100%;
  font-size: 22px;
  font-weight: 700;
  color: var(--gradient-1);
  margin-bottom: 16px;
}
.welcome-content[data-v-fc8ab866] {
  width: 100%;
}
</style>
